package openapi;

import java.io.InputStream;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Properties;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import net.sf.json.xml.XMLSerializer;
import openapi.dto.ApiCommonParamDto;
import openapi.util.ResUtils;
import openapi.util.SignUtil;
import openapi.util.XmlUtils;

public class SampleWsInvoke {

	private static final String SIGN_METHOD_RSA = "RSA";
	
	public static void main(String[] args) throws Exception {

		Properties properties = new Properties();
		InputStream inputStream = SampleWsInvoke.class.getClassLoader().getResourceAsStream("ws/ws-config.properties");
		try {
			properties.load(inputStream);
		} finally {
			inputStream.close();
		}
		String wsUrl = properties.getProperty("WSURL");
		String sysId = properties.getProperty("SYSID");
		String appSubId = properties.getProperty("APPSUBID");
		String appPubId = properties.getProperty("APPPUBID");
		String partnerId = properties.getProperty("PARTNERID");
		String apiId = properties.getProperty("APIID");
		String apiVersion = properties.getProperty("APIVERSION");
		String formatterStr = properties.getProperty("FORMATTER");
		String appToken = properties.getProperty("APPTOKEN");
		String appAppSecret = properties.getProperty("APPAPPSECRET");
		String format = properties.getProperty("FORMAT");
		String signMethod = properties.getProperty("SIGNMETHOD");
		String privateKey = properties.getProperty("PrivateKey");

		SimpleDateFormat sdf = new SimpleDateFormat(formatterStr);
		String timeStamp = sdf.format(new java.util.Date());
		
		String location = "ws/ws_data.xml";
		String requestData = ResUtils.readFileContent(location);
		
		ApiCommonParamDto dto = new ApiCommonParamDto();
		dto.setApiVersion(apiVersion);
		dto.setApiID(apiId);
		dto.setAppToken(appToken);
		dto.setSysID(sysId);
		dto.setAppSubId(appSubId);
		dto.setPartnerID(partnerId);
		dto.setAppPubID(appPubId);
		dto.setTimeStamp(timeStamp);
		dto.setSignMethod(signMethod);
		dto.setFormat(format);
		dto.setReqdate(requestData);
		String sign=SignUtil.md5_sign(dto, appAppSecret);
		if(SIGN_METHOD_RSA.equalsIgnoreCase(signMethod)){
			// 如果是RSA,将md5加密后的字符再进行RSA加密
			sign = SignUtil.rsa_encryptByPrivateKey(sign, privateKey);
		}
		dto.setSign(sign);
		
		boolean isRest = false;
		String xml = toXml(isRest, dto);
		String responseData = doTestSoap(wsUrl, xml);
		System.out.println(responseData);
		
		XMLSerializer xmlSerializer=new XMLSerializer();
		String xml_json =xmlSerializer.read(responseData).toString();
		System.out.println(xml_json);
		// 
		JSONObject jsonObject = JSON.parseObject(xml_json);
		System.out.println();
		System.out.println( jsonObject.get("RETURN_CODE") );
		System.out.println( jsonObject.get("RETURN_STAMP") );
		System.out.println( jsonObject.get("RETURN_DATA") );
		System.out.println( jsonObject.get("RETURN_DESC") );
		
	}
	
	
	public static String doTestSoap(String url, String xml) {
		String result = "";
		CloseableHttpClient httpclient = null;
		try {
			httpclient = HttpClients.createDefault();
			HttpPost httpPost = new HttpPost(url);
			httpPost.addHeader("Content-type","application/xml; charset=utf-8");
			httpPost.setHeader("Accept", "application/xml");
			StringEntity se = new StringEntity(xml, Charset.forName("UTF-8"));
			se.setContentType("application/xml");
			httpPost.setEntity(se);
			CloseableHttpResponse response = httpclient.execute(httpPost);
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				result = EntityUtils.toString(entity, "UTF-8");
			}
			httpclient.close();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {

		}
		return result;
	}
	
	public static String toXml(boolean isRest, ApiCommonParamDto dto) throws Exception {
		StringBuilder sb = new StringBuilder(100);
		String token = dto.getAppToken();
		dto.setAppToken(null);
		String hrtAttrs = XmlUtils.bean2xml(dto);
		if(isRest){//restful的xml格式
			sb.append("<REQUEST>");
			sb.append(hrtAttrs);
			//sb.append("<REQUEST_DATA>");
			sb.append(dto.getReqdate());
			addToken(sb, token);
			//sb.append("</REQUEST_DATA>");
			sb.append("</REQUEST>");
		}else{
			//soap的报文格式，这里手动拼接
			sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
			sb.append("<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">");
			sb.append("<SOAP-ENV:Body>");
			sb.append("<REQUEST>");
			sb.append(hrtAttrs);
			addToken(sb, token);
			//sb.append("<REQUEST_DATA>");
			sb.append(dto.getReqdate());
			//sb.append("</REQUEST_DATA>");
			sb.append("</REQUEST>");
			sb.append("</SOAP-ENV:Body>");
			sb.append("</SOAP-ENV:Envelope>");
		}
		return sb.toString();
	}
	
	private static void addToken(StringBuilder sb, String token){
		//在</HRT_ATTRS>前面加上<App_Token>5b260c957c0d44429f10af2e551599e3</App_Token>
		int lastIndexOf = StringUtils.lastIndexOf(sb.toString(), "</HRT_ATTRS>");
		token =  "<App_Token>"+ token + "</App_Token>";
		sb.insert(lastIndexOf, token);
	}
	
}
